﻿using Caliburn.Micro;
using Microsoft.Win32;
using SD.Common;
using SD.Infrastructure.DTOBase;
using SD.Infrastructure.WPF.Caliburn.Aspects;
using SD.Infrastructure.WPF.Caliburn.Base;
using SD.Infrastructure.WPF.Extensions;
using SD.Infrastructure.WPF.Models;
using SD.IOC.Core.Mediators;
using SD.Toolkits.Excel;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.ServiceModel.Extensions;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using SlamDunk.MES.Client.ViewModels.ExecutionPlan;
using SlamDunk.MES.IAppService.DTOs.Outputs.ConfigurationContext;
using SlamDunk.MES.IAppService.DTOs.Outputs.ExecutionContext;
using SlamDunk.MES.IAppService.Interfaces;
using SlamDunk.MES.Presentation;
using SlamDunk.MES.Presentation.Maps;
using SlamDunk.MES.Presentation.Models.ExportModels;
using SlamDunk.ValueObjects.Enums;
using LookViewModel = SlamDunk.MES.Client.ViewModels.Execution.LookViewModel;

namespace SlamDunk.MES.Client.ViewModels.Schedule
{
    /// <summary>
    /// 作业调度首页ViewModel
    /// </summary>
    public class IndexViewModel : ScreenBase
    {
        #region # 字段及构造器

        /// <summary>
        /// 库存单据服务契约接口代理
        /// </summary>
        private readonly ServiceProxy<IExecutionContract> _iExecutionContract;

        /// <summary>
        /// 窗口管理器
        /// </summary>
        private readonly IWindowManager _windowManager;

        /// <summary>
        /// 依赖注入构造器
        /// </summary>
        public IndexViewModel(ServiceProxy<IExecutionContract> iExecutionContract, IWindowManager windowManager)
        {
            this._iExecutionContract = iExecutionContract;
            this._windowManager = windowManager;

            //默认值
            this.PageIndex = 1;
            this.PageSize = 20;
        }

        #endregion

        #region # 属性

        #region 页码 —— int PageIndex
        /// <summary>
        /// 页码
        /// </summary>
        [DependencyProperty]
        public int PageIndex { get; set; }
        #endregion

        #region 页容量 —— int PageSize
        /// <summary>
        /// 页容量
        /// </summary>
        [DependencyProperty]
        public int PageSize { get; set; }
        #endregion

        #region 总记录数 —— int RowCount
        /// <summary>
        /// 总记录数
        /// </summary>
        [DependencyProperty]
        public int RowCount { get; set; }
        #endregion

        #region 总页数 —— int PageCount
        /// <summary>
        /// 总页数
        /// </summary>
        [DependencyProperty]
        public int PageCount { get; set; }
        #endregion

        #region 关键字
        /// <summary>
        /// 关键字
        /// </summary>
        [DependencyProperty]
        public string Keywords { get; set; }
        #endregion

        #region 开始时间
        /// <summary>
        /// 开始时间
        /// </summary>
        [DependencyProperty]
        public DateTime? StartTime { get; set; }
        #endregion

        #region 结束时间
        /// <summary>
        /// 结束时间
        /// </summary>
        [DependencyProperty]
        public DateTime? EndTime { get; set; }
        #endregion

        #region 工单状态列表
        /// <summary>
        /// 工单状态列表
        /// </summary>
        [DependencyProperty]
        public IDictionary<string, string> WorkOrderStatusList { get; set; }
        #endregion

        #region 已选工单状态 —— WorkOrderStatus? SelectedWorkOrderStatus
        /// <summary>
        /// 已选工单状态
        /// </summary>
        [DependencyProperty]
        public WorkOrderStatus? SelectedWorkOrderStatus { get; set; }
        #endregion

        #region 工单列表
        /// <summary>
        /// 工单列表
        /// </summary>
        [DependencyProperty]
        public ObservableCollection<Wrap<WorkOrderInfo>> WorkOrders { get; set; }
        #endregion

        #endregion

        #region # 方法

        //Initializations

        #region 初始化 —— override async Task OnInitializeAsync(CancellationToken cancellationToken)
        /// <summary>
        /// 初始化
        /// </summary>
        protected override async Task OnInitializeAsync(CancellationToken cancellationToken)
        {
            this.WorkOrderStatusList = typeof(WorkOrderStatus).GetEnumMembers();
            await this.ReloadWorkOrders();
        }
        #endregion


        //Actions

        #region 加载工单列表 —— async void LoadWorkOrders()
        /// <summary>
        /// 加载工单列表
        /// </summary>
        public async void LoadWorkOrders()
        {
            await this.ReloadWorkOrders();
        }
        #endregion

        #region 生成工单 —— async void GenerateWorkOrders()
        /// <summary>
        /// 生成工单
        /// </summary>
        public async void GenerateWorkOrders()
        {
            SelectExecutionPlanViewModel viewModel = ResolveMediator.Resolve<SelectExecutionPlanViewModel>();
            viewModel.Load(false, null, ExecutionPlanStatus.Released, false);
            bool? result = await this._windowManager.ShowDialogAsync(viewModel);
            if (result == true)
            {
                var ExecutionPlanInfo = viewModel.ExecutionPlans.Where(x => x.IsChecked == true).FirstOrDefault();
                await Task.Run(() => this._iExecutionContract.Channel.GenerateWorkOrders(ExecutionPlanInfo.Model.Id));
                await this.ReloadWorkOrders();
            }
        }
        #endregion

        #region 工单分派 —— async void DispatchWorkOrder()
        /// <summary>
        /// 工单分派
        /// </summary>
        public async void DispatchWorkOrder()
        {
            #region # 验证
            WorkOrderInfo[] checkedRoles = this.WorkOrders.Where(x => x.IsChecked == true).Select(x => x.Model).ToArray();
            if (!checkedRoles.Any() || checkedRoles.Count() != 1)
            {
                MessageBox.Show("请勾选一条工单信息！", "警告", MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }
            if (checkedRoles.FirstOrDefault().Status != WorkOrderStatus.Ready)
            {
                MessageBox.Show("勾选工单信息不可分派，只有准备状态的单据可进行分派！", "警告", MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }
            #endregion

            DispatchViewModel viewModel = ResolveMediator.Resolve<DispatchViewModel>();
            await viewModel.Load(checkedRoles.FirstOrDefault());
            bool? result = await this._windowManager.ShowDialogAsync(viewModel);
            if (result == true)
            {
                await this.ReloadWorkOrders();
            }
        }
        #endregion

        #region 取消工单 —— async void CancelWorkOrder()
        /// <summary>
        /// 取消工单
        /// </summary>
        public async void CancelWorkOrder()
        {
            #region # 验证

            WorkOrderInfo[] checkedWorkOrders = this.WorkOrders.Where(x => x.IsChecked == true).Select(x => x.Model).ToArray();
            if (!checkedWorkOrders.Any())
            {
                MessageBox.Show("请勾选一条工单信息！", "警告", MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }

            #endregion

            WorkOrderInfo workOrderInfo = checkedWorkOrders.Single();

            #region # 验证

            if (workOrderInfo.Status != WorkOrderStatus.Ready)
            {
                MessageBox.Show("只有准备状态的工单可以取消！", "警告", MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }

            #endregion

            MessageBoxResult result = MessageBox.Show("确定要取消吗？", "警告", MessageBoxButton.YesNo, MessageBoxImage.Warning);
            if (result == MessageBoxResult.Yes)
            {
                this.Busy();

                await Task.Run(() => this._iExecutionContract.Channel.CancelWorkOrder(workOrderInfo.Id, null));
                await this.ReloadWorkOrders();

                this.Idle();
            }
        }
        #endregion

        #region 工单查看 —— async void WorkOrderActualParameter()
        /// <summary>
        /// 工单查看
        /// </summary>
        /// <param name=""></param>
        public async void LookWorkOrde()
        {
            #region # 验证

            WorkOrderInfo[] checkedWorkOrders = this.WorkOrders.Where(x => x.IsChecked == true).Select(x => x.Model).ToArray();
            if (!checkedWorkOrders.Any())
            {
                MessageBox.Show("请勾选一条工单信息！", "警告", MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }

            #endregion

            LookViewModel viewModel = ResolveMediator.Resolve<LookViewModel>();
            viewModel.Load(checkedWorkOrders.Single());
            await this._windowManager.ShowDialogAsync(viewModel);
        }
        #endregion

        #region 全选 —— void CheckAll()
        /// <summary>
        /// 全选
        /// </summary>
        public void CheckAll()
        {
            this.WorkOrders.ForEach(x => x.IsChecked = true);
        }
        #endregion

        #region 取消全选 —— void UncheckAll()
        /// <summary>
        /// 取消全选
        /// </summary>
        public void UncheckAll()
        {
            this.WorkOrders.ForEach(x => x.IsChecked = false);
        }
        #endregion

        #region 打印派工单 —— async void PrintWorkOrdes()
        /// <summary>
        /// 打印派工单
        /// </summary>
        public async void PrintWorkOrdes()
        {
            #region # 验证

            if (this.WorkOrders.All(x => x.IsChecked != true))
            {
                MessageBox.Show("请勾选至少一条要打印的工单！", "警告", MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }

            #endregion

            IEnumerable<Wrap<WorkOrderInfo>> checkedWraps = this.WorkOrders.Where(x => x.IsChecked == true);

            this.Busy();

            PrintViewModel viewModel = ResolveMediator.Resolve<PrintViewModel>();
            viewModel.Load(checkedWraps.Select(x => x.Model));
            await this._windowManager.ShowDialogAsync(viewModel);

            this.Idle();
        }
        #endregion

        #region 导出
        /// <summary>
        /// 导出
        /// </summary>
        public async void Export()
        {
            IList<WorkOrderStatus> statuses = new List<WorkOrderStatus>();
            if (this.SelectedWorkOrderStatus.HasValue)
            {
                statuses.Add(SelectedWorkOrderStatus.Value);
            }

            UserExtensionInfo userExtensionInfo = (UserExtensionInfo)AppDomain.CurrentDomain.GetData(Constants.UserExtensionKey);
            PageModel<WorkOrderInfo> pageModel = await Task.Run(() => this._iExecutionContract.Channel.GetWorkOrdersByPage(
                Keywords,//关键字
                null,//生产计划Id
                null, //作业计划Id
                null, //工艺段Id
                null, //工位Id
                null, //是否需质检
                null,//是否已质检
                userExtensionInfo?.TeamInfo?.Id,//分派班组Id
                null,//分派人员Id
                StartTime, //开始时间
                EndTime, //结束时间
                null, //工厂模型Id
                statuses, //工单状态集
                1,//页码
                int.MaxValue));

            WorkOrderEm[] workOrderEms = pageModel.Datas.Select(x => x.ToExportView()).ToArray();
            if (!workOrderEms.Any())
            {
                MessageBox.Show("导出数据为空，不能进行导出！", "警告", MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }

            SaveFileDialog saveFileDialog = new SaveFileDialog
            {
                Filter = Constants.ExeclFileExtensionsFilter,
                FileName = $"工单_{DateTime.Now.ToString(Constants.ExportFileTimeFormat)}",
                AddExtension = true,
                RestoreDirectory = true
            };
            if (saveFileDialog.ShowDialog() == true)
            {
                string filePath = saveFileDialog.FileName;
                ExcelWriter.WriteFile(workOrderEms, filePath);
            }
        }
        #endregion
        //Private

        #region 加载工单列表 —— async Task ReloadWorkOrders()
        /// <summary>
        /// 加载工单班组列表
        /// </summary>
        private async Task ReloadWorkOrders()
        {
            this.Busy();

            IList<WorkOrderStatus> statuses = new List<WorkOrderStatus>();
            if (this.SelectedWorkOrderStatus.HasValue)
            {
                statuses.Add(SelectedWorkOrderStatus.Value);
            }

            UserExtensionInfo userExtensionInfo = (UserExtensionInfo)AppDomain.CurrentDomain.GetData(Constants.UserExtensionKey);
            PageModel<WorkOrderInfo> pageModel = await Task.Run(() => this._iExecutionContract.Channel.GetWorkOrdersByPage(
                Keywords,//关键字
                null,//生产计划Id
                null, //作业计划Id
                null, //工艺段Id
                null, //工位Id
                null, //是否需质检
                null,//是否已质检
                userExtensionInfo?.TeamInfo?.Id,//分派班组Id
                null,//分派人员Id
                StartTime, //开始时间
                EndTime, //结束时间
                null, //工厂模型Id
                statuses, //工单状态集
                this.PageIndex,//页码
                this.PageSize));
            this.RowCount = pageModel.RowCount;
            this.PageCount = pageModel.PageCount;

            IEnumerable<Wrap<WorkOrderInfo>> wrapModels = pageModel.Datas.Select(x => x.Wrap());
            this.WorkOrders = new ObservableCollection<Wrap<WorkOrderInfo>>(wrapModels);

            this.Idle();
        }
        #endregion

        #endregion
    }
}
